package com.kedacom.demo.emailgateway.service;

import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.mail.Address;
import javax.mail.MessagingException;
import javax.mail.SendFailedException;
import javax.mail.internet.MimeMessage;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.mail.MailSendException;
import org.springframework.mail.javamail.JavaMailSenderImpl;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import com.kedacom.demo.emailgateway.core.annotation.Properties;
import com.kedacom.demo.emailgateway.exception.BusinessException;
import com.kedacom.demo.emailgateway.model.Email;
import com.kedacom.demo.emailgateway.model.UnderwayEmail;
import com.kedacom.demo.emailgateway.model.UnderwayEmailSendToManyUser;

@Component("emailGatewayHelper")
public class EmailGatewayHelper {
	protected Logger logger = LoggerFactory.getLogger(getClass());
	private JavaMailSenderImpl mailSender;

	@Properties(name = "app.mail.server.host")
	private static String host;
	@Properties(name = "app.mail.server.username")
	private String username;
	@Properties(name = "app.mail.server.password")
	private String password;
	@Properties(name = "app.mail.smtp.auth")
	private String auth;
	@Properties(name = "app.mail.smtp.timeout")
	private String timeout;
	@Properties(name = "mail.send")
	private String mailSend;

	private void init() {
		mailSender = new JavaMailSenderImpl();
		mailSender.setHost(host);
		mailSender.setUsername(username);
		mailSender.setPassword(password);
		mailSender.getJavaMailProperties().setProperty("mail.smtp.auth", auth);
		mailSender.getJavaMailProperties().setProperty("mail.smtp.timeout", timeout);
	}

	/**
	 * 单个收件人
	 * 
	 * @param mail
	 * @throws MessagingException
	 */
	public void sendMimeMailByMailSender(UnderwayEmail mail) throws MessagingException {
		doSend(mail);
	}

	private void doSend(Email mail) throws MessagingException {
		if (StringUtils.hasText(mailSend) && Boolean.valueOf(mailSend)) {
			init();
			MimeMessage message = mailSender.createMimeMessage();
			message.setHeader("Content-Type", "text/htm;charset=UTF-8");
			message.setHeader("Content-Language", "UTF-8");
			MimeMessageHelper helper = new MimeMessageHelper(message, "UTF-8");
			helper.setSentDate(new Date());
			helper.setSubject(mail.getSubject());
			helper.setText(
					mail.getText().replaceFirst("</body>",
							"<br/><br/><div><font color='red'>此邮件为系统自动发送，请勿回复！</font></div></body>"), true);
			String[] mailAddr = org.springframework.util.StringUtils.commaDelimitedListToStringArray(mail.getTo());

			// 删除错误的以及重复的收件人email地址
			List<String> correctAddresses = new ArrayList<String>();
			for (String address : mailAddr) {
				if (isCorrectEmailAddress(address) && !correctAddresses.contains(address)) {
					correctAddresses.add(address);
				}
			}
			helper.setFrom(mail.getFrom());
			helper.setTo(org.springframework.util.StringUtils
					.commaDelimitedListToStringArray(org.springframework.util.StringUtils
							.collectionToCommaDelimitedString(correctAddresses)));
			message.setHeader("Content-Transfer-Encoding", "base64");
			mailSender.send(message);
		}
	}

	/**
	 * 多个收件人
	 * 
	 * @param mail
	 * @throws MessagingException
	 */
	public void sendMimeMailByMailSender(UnderwayEmailSendToManyUser mail) throws MessagingException {
		try {
			doSend(mail);
		} catch (MailSendException me) {
			Map<Object, Exception> mp = me.getFailedMessages();
			if (mp != null && mp.values() != null) {
				Iterator<Exception> iter = mp.values().iterator();
				while (iter.hasNext()) {
					Object obj = iter.next();
					if (obj instanceof SendFailedException) {
						SendFailedException se = (SendFailedException) obj;
						Address[] invalid = se.getInvalidAddresses();
						Address[] validUnsent = se.getValidUnsentAddresses();
						if (validUnsent != null && validUnsent.length > 0) {
							String successEmail = convertoAddressArrToString(validUnsent);
							mail.setTo(successEmail);
							doSend(mail);
							throw new BusinessException(successEmail + "发送成功，" + convertoAddressArrToString(invalid)
									+ "发送失败。");
						}
					}
				}
			}
			throw new MailSendException(me.getMessage());
		}
	}

	/**
	 * 将地址的数组转换成字符串
	 * 
	 * @param arr
	 * @return
	 */
	private String convertoAddressArrToString(Address[] arr) {
		StringBuffer unsent = new StringBuffer();
		if (arr != null && arr.length > 0) {
			for (int i = 0; i < arr.length; i++) {
				if (StringUtils.hasText(unsent)) {
					unsent.append(",");
				}
				unsent.append(arr[i]);
			}
		}
		return unsent.toString();
	}

	private boolean isCorrectEmailAddress(String emailAddress) {
		return org.springframework.util.StringUtils.hasText(emailAddress) && emailAddress.indexOf("@") >= 0
				&& !org.springframework.util.StringUtils.startsWithIgnoreCase(emailAddress, "@")
				&& !org.springframework.util.StringUtils.endsWithIgnoreCase(emailAddress, "@");
	}

	public String getHost() {
		return host;
	}

	public void setHost(String host) {
		this.host = host;
	}

	public String getUsername() {
		return username;
	}

	public void setUsername(String username) {
		this.username = username;
	}

	public String getPassword() {
		return password;
	}

	public void setPassword(String password) {
		this.password = password;
	}

	public String getAuth() {
		return auth;
	}

	public void setAuth(String auth) {
		this.auth = auth;
	}

	public String getTimeout() {
		return timeout;
	}

	public void setTimeout(String timeout) {
		this.timeout = timeout;
	}

	public String getMailSend() {
		return mailSend;
	}

	public void setMailSend(String mailSend) {
		this.mailSend = mailSend;
	}
}
